﻿@model WebEditor.Models.Script
@using TextAdventures.Quest;
@using WebEditor.Views.Edit;

@RenderScripts(Model.Scripts, Model.Attribute)

@helper RenderScripts(IEditableScripts scripts, string attribute)
{
    <div class="ui-widget-header ui-corner-all toolbar script-toolbar" id="script-toolbar-@attribute" data-key="@attribute" style="display: none">
        <button type="button" class="script-delete" data-key="@attribute">Delete</button>
        <span class="script-clipboard">
            <button type="button" class="script-cut" data-key="@attribute">Cut</button>
            <button type="button" class="script-copy" data-key="@attribute">Copy</button>
        </span>
        <span class="script-move">
            <button type="button" class="script-moveup" data-key="@attribute">Move up</button>
            <button type="button" class="script-movedown" data-key="@attribute">Move down</button>
        </span>
    </div>

    <div class="ui-corner-all scriptEditor">
        @{
            if (scripts != null) {
                int count = 0;
                foreach (IEditableScript script in scripts.Scripts)
                {
                    if (Html.ViewData.ModelState.ContainsKey(script.Id) && Html.ViewData.ModelState[script.Id].Errors.Count > 0)
                    {
                        <div class="elementEditorError">
                            @Html.ValidationMessage(script.Id)
                            <button type="button" class="error-clear" data-key="@script.Id">Clear</button>
                        </div>
                    }
                    bool isSelected = Model.SelectedScripts.Contains(script);
                    IEditorDefinition definition = Model.Controller.GetEditorDefinition(script);
                    <div class="scriptLine">
                        @Html.CheckBox("selected-" + attribute + "-" + count.ToString(), isSelected, new { @class = "script-select", data_key = attribute })
                        @if (script.Type != ScriptType.If)
                        {
                            IEditorData scriptEditorData = Model.Controller.GetScriptEditorData(script);
                            foreach (IEditorControl ctl in definition.Controls)
                            {
                                if (ctl.GetBool("breakbefore"))
                                {
                                    <br /><text>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</text>
                                }
                                else
                                {
                                    <text> </text>
                                }
                                object value = ctl.Attribute == null ? null : scriptEditorData.GetAttribute(ctl.Attribute);
                                @RenderEditorControl(ctl, value, attribute + "-" + count.ToString())
                            }
                        }
                        else
                        {
                            @RenderIfScript((EditableIfScript)script, attribute + "-" + count.ToString())
                        }
                    </div>
                    count++;
                }
            }
        }

        <button type="button" class="script-add" data-key="@attribute">Add new script</button>
        @if (Model.Controller.CanPasteScript())
        {
            <button type="button" class="script-paste" data-key="@attribute">Paste</button>
        }
        @{
            string code = scripts == null ? null : scripts.Code;
        }
        @if (!Model.Controller.SimpleMode)
        {
            <button type="button" id="script-codeview-@attribute" class="script-codeview" data-key="@attribute" data-code="@code">Code View</button>
        }
    </div>
}

@helper RenderEditorControl(IEditorControl ctl, object value, string attributePrefix)
{
    string name = attributePrefix + "-" + ctl.Attribute;
    switch (ctl.ControlType)
    {
        case "checkbox":
            @Html.CheckBox(name, value as bool? == true)
            @Html.Label(name, ctl.Caption)
            break;
        case "textbox":
            bool multiLine = ctl.GetBool("multiline");
            if (multiLine)
            {
                string colour = ctl.GetString("colour");
                string extraStyle = "";
                if (colour != null)
                {
                    extraStyle = "color: " + colour;
                }
                @Html.TextArea(name, (string)value, new { style = "width: 350px; " + extraStyle, @class = "elementEditorTextbox" });
            }
            else
            {
                @Html.TextBox(name, (string)value, new { @class = "elementEditorTextbox" })
            }
            break;
        case "label":
            @ctl.Caption
            break;
        case "dropdown":
            IEnumerable<SelectListItem> valuesList = WebEditor.Views.Edit.ControlHelpers.GetDropdownValues(ctl, (string)value, Model.Controller);
            @Html.DropDownList(name, valuesList);
            break;
        case "expression":
            @RenderExpressionControl(ctl, name, (string)value)
            break;
        case "script":
            string caption = ctl.GetString("caption");
            if (caption != null)
            {
                <text>@caption:</text>
            }
            <div class="childScript">
            @RenderScripts((IEditableScripts)value, name)
            </div>
            break;
        case "scriptdictionary":
            @Html.Action("EditScriptScriptDictionary", new { id = Model.GameId, key = Model.Key, path = name, control = ctl })
            break;
        case "list":
            <div class="scriptStringListSection">
            @Html.Action("EditScriptStringList", new { id = Model.GameId, key = Model.Key, path = name, control = ctl })
            </div>
            break;
        default:
            <text>[@ctl.ControlType]</text>
            break;
    }
}

@helper RenderExpressionControl(IEditorControl ctl, string name, string value)
{
    string templatesFilter = ctl.GetString("usetemplates");

    if (templatesFilter != null)
    {
        @RenderTemplateControl(name, value, templatesFilter);
        return;
    }

    string simpleEditor = ctl.GetString("simpleeditor") ?? "textbox";
    string simple = ctl.GetString("simple");

    if (simpleEditor == "boolean" || simpleEditor != null)
    {
        List<SelectListItem> list = new List<SelectListItem>();
        MvcHtmlString editorHtml = null;
        bool simpleEditorVisible = (simple != null || simpleEditor == "boolean") && IsSimpleExpression(ctl, simpleEditor, value);
        string simpleValue = simpleEditorVisible ? ConvertToSimpleExpression(simpleEditor, value) : string.Empty;
        
        switch (simpleEditor)
        {
            case "textbox":
                bool multiLine = ctl.GetBool("multiline");
                if (multiLine)
                {
                    editorHtml = Html.TextArea(name + "-simpleeditor", simpleValue, new { style = "width: 350px", @class = "elementEditorTextbox" });
                }
                else
                {
                    editorHtml = Html.TextBox(name + "-simpleeditor", simpleValue, new { style = "width: 350px", @class = "elementEditorTextbox" });
                }
                break;
            case "file":
                MvcHtmlString textBox = Html.TextBox(name + "-simpleeditor", simpleValue, new { style = "width: 200px", @readonly = "readonly" });
                string source = string.Join(";", ctl.GetString("source").Split(';').Select(s => s.Substring(1)));                
                Func<int, object> button = @<text><button type="button" class="file-upload" data-key="@name-simpleeditor" data-extensions="@source">Choose file</button></text>;
                Func<int, object> previewBtn = @<text>
                    <button type="button" class="img-preview" data-key="@name-simpleeditor" data-extensions="@source">
                        <img src="/ImageProcessor.ashx?h=40&w=40&gameId=@Model.GameId&image=@simpleValue" />
                    </button>
                 </text>;
                MvcHtmlString imageDiv = ctl.GetBool("preview") && source.Contains("jpg") && !string.IsNullOrEmpty(simpleValue) ? MvcHtmlString.Create(previewBtn(0).ToString()) : MvcHtmlString.Empty;

                editorHtml = MvcHtmlString.Create(textBox.ToString() + imageDiv.ToString() + button(0).ToString());
                break;
            case "boolean":
                list.Add(new SelectListItem { Text = "yes", Selected = (value == "true") });
                list.Add(new SelectListItem { Text = "no", Selected = (value == "false") });
                break;
            case "objects":
                List<SelectListItem> items = new List<SelectListItem>(
                    ControlHelpers.GetObjectListNames(ctl, Model.Controller).OrderBy(s => s, StringComparer.CurrentCultureIgnoreCase)
                    .Select(s => new SelectListItem { Text = s, Value = s, Selected = (value == s) })
                    );
                editorHtml = Html.DropDownList(name + "-simpleeditor", items, new { @class = "elementEditorDropdown" });
                break;
            case "number":
                editorHtml = new MvcHtmlString("<input type=\"number\" name=\"" + name + "-simpleeditor\" id=\"" + name + "-simpleeditor\"  value=\"" + simpleValue + "\" style=\"width: 50px\" />");
                break;
            case "numberdouble":
                editorHtml = new MvcHtmlString("<input type=\"text\" name=\"" + name + "-simpleeditor\" id=\"" + name + "-simpleeditor\"  value=\"" + simpleValue + "\" style=\"width: 50px\" />");
                break;
            case "dropdown":
                IEnumerable<SelectListItem> valuesList = WebEditor.Views.Edit.ControlHelpers.GetDropdownValues(ctl, simpleValue, Model.Controller);
                editorHtml = Html.DropDownList(name + "-simpleeditor", valuesList, new { @class = "elementEditorDropdown" });
                break;
            default:
                throw new InvalidOperationException("Invalid control type for expression");
        }

        if (editorHtml != null && (simple != null || simpleEditor == "boolean"))
        {
            list.Add(new SelectListItem { Text = simple, Selected = simpleEditorVisible });
        }

        if (list.Count > 0)
        {
            list.Add(new SelectListItem { Text = "expression", Selected = !simpleEditorVisible });
            @Html.DropDownList(name + "-expressioneditordropdown", list, new { @class = "expression-dropdown elementEditorDropdown", data_key = name })
        }

        string simpleEditorDisplayStyle = simpleEditorVisible ? "inline" : "none";
        string expressionDisplayStyle = simpleEditorVisible ? "none" : "inline";

        @Html.TextBox(name + "-expressioneditor", value, new { style = "width: 350px; display: " + expressionDisplayStyle, @class = "elementEditorTextbox" });

                                                                                                                                                             if (editorHtml != null)
                                                                                                                                                             {
            <span id="@name-simpleeditorspan" style="display: @simpleEditorDisplayStyle">@editorHtml</span>
                                                                                                                                                             }
    }
}

@helper RenderTemplateControl(string name, string value, string templatesFilter)
    {
    IEditorDefinition editorDefinition = Model.Controller.GetExpressionEditorDefinition(value, templatesFilter);
    bool useTemplate = (editorDefinition != null);
    string templateName = null;
    List<SelectListItem> list = new List<SelectListItem>();

    list.Add(new SelectListItem { Text = "expression", Selected = !useTemplate });

    if (useTemplate)
    {
        templateName = Model.Controller.GetExpressionEditorDefinitionName(value, templatesFilter);
    }

    foreach (string item in Model.Controller.GetExpressionEditorNames(templatesFilter))
    {
        list.Add(new SelectListItem { Text = item, Selected = (item == templateName) });
    }
    
    @Html.DropDownList(name + "-templatedropdown", list, new { @class = "template-dropdown", data_key = name })

    string expressionVisibility = "inline";

    if (useTemplate)
    {
        string templateEditorControlsSpanName = name + "-templateeditor";
        <span id="@templateEditorControlsSpanName">
            @{
        expressionVisibility = "none";
        int count = 0;
        IEditorData data = Model.Controller.GetExpressionEditorData(value, templatesFilter, null);
        foreach (IEditorControl ctl in editorDefinition.Controls)
        {
            object editorValue = ctl.Attribute == null ? null : data.GetAttribute(ctl.Attribute);
                    @RenderEditorControl(ctl, editorValue, name)
            count++;
        }
            }
        </span>
    }
    
    @Html.TextBox(name, value, new { style = "width: 350px; display: " + expressionVisibility });
}

@helper RenderIfScript(EditableIfScript script, string attributePrefix)
    {
    <text>If: </text>
    @RenderTemplateControl(attributePrefix + "-expression", (string)script.GetAttribute("expression"), "if")
    <div class="childScript">
    @RenderScripts(script.ThenScript, attributePrefix + "-then")
    </div>
    
    <div class="ifSection ui-widget-header ui-corner-all toolbar" id="ifsection-toolbar-@attributePrefix" style="display: none">
        <button type="button" class="ifsection-delete" data-key="@attributePrefix">Remove section</button>
    </div>
    
    int elseIfCount = 0;
    foreach (EditableIfScript.EditableElseIf elseIf in script.ElseIfScripts)
    {
        <div class="ifSection">
        @Html.CheckBox("selectifsection-" + attributePrefix + "-elseif" + elseIfCount.ToString(), new { @class = "ifsection-select", data_key = attributePrefix })
        Else If:
        @RenderTemplateControl(attributePrefix + "-elseif" + elseIfCount.ToString() + "-expression", (string)elseIf.GetAttribute("expression"), "if")
        </div>
        <div class="childScript">
        @RenderScripts(elseIf.EditableScripts, attributePrefix + "-elseif" + elseIfCount.ToString())
        </div>

        elseIfCount++;
    }
    
    <div class="ifSection"><button type="button" class="script-if-add-elseif" data-key="@attributePrefix">Add Else If</button></div>

    if (script.ElseScript == null)
    {
        <div class="ifSection">
        <button type="button" class="script-if-add-else" data-key="@attributePrefix">Add Else</button>
        </div>
    }
    else
    {
        <div class="ifSection">
        @Html.CheckBox("selectifsection-" + attributePrefix + "-else", new { @class = "ifsection-select", data_key = attributePrefix })
        Else:
        </div>
        <div class="childScript">
        @RenderScripts(script.ElseScript, attributePrefix + "-else")
        </div>
    }
}

@functions {
    private bool IsSimpleExpression(IEditorControl ctl, string simpleEditor, string expression)
    {
        if (simpleEditor == "boolean")
        {
            return (expression == "true" || expression == "false");
        }

        if (simpleEditor == "objects")
        {
            return expression.Length == 0  || ControlHelpers.GetObjectListNames(ctl, Model.Controller).Contains(expression);
        }

        if (simpleEditor == "number")
        {
            int number;
            return int.TryParse(expression, out number);
        }

        if (simpleEditor == "numberdouble")
        {
            double number;
            return double.TryParse(expression, out number);
        }

        return EditorUtility.IsSimpleStringExpression(expression);
    }

    private string ConvertToSimpleExpression(string simpleEditor, string expression)
    {
        switch (simpleEditor)
        {
            case "boolean":
            case "objects":
            case "number":
            case "numberdouble":
                return expression;
            default:
                return EditorUtility.ConvertToSimpleStringExpression(expression);
        }
    }


}